cpuidle: Fix for timer_deadline==0 case
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 30 Apr 2009 09:05:00 +0000 (10:05 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 30 Apr 2009 09:05:00 +0000 (10:05 +0100)
After the scheduler timer became suspended before entering cpu idle
state, the percpu timer_deadline is possible to be 0, i.e. no soft
timer in the queue. This case will cause unexpected large residency
percentage in C1 for the purely idle cpu.

Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hpet.c

index 40a0b1622e05912db5ec19148ab2fde0362646c8..e66eedee73b5994a07df516ac0b64bade61fd6e9 100644 (file)
@@ -25,7 +25,7 @@
 #define HPET_EVT_USED_BIT    0
 #define HPET_EVT_USED       (1 << HPET_EVT_USED_BIT)
 #define HPET_EVT_DISABLE_BIT 1
-#define HPET_EVT_DISALBE    (1 << HPET_EVT_DISABLE_BIT)
+#define HPET_EVT_DISABLE    (1 << HPET_EVT_DISABLE_BIT)
 
 struct hpet_event_channel
 {
@@ -119,12 +119,12 @@ static int reprogram_hpet_evt_channel(
     int64_t delta;
     int ret;
 
-    if ( ch->flags & HPET_EVT_DISALBE )
+    if ( (ch->flags & HPET_EVT_DISABLE) || (expire == 0) )
         return 0;
 
     if ( unlikely(expire < 0) )
     {
-        printk(KERN_DEBUG "reprogram: expire < 0\n");
+        printk(KERN_DEBUG "reprogram: expire <= 0\n");
         return -ETIME;
     }
 
@@ -560,7 +560,7 @@ void hpet_broadcast_init(void)
         return;
     }
 
-    if ( legacy_hpet_event.flags & HPET_EVT_DISALBE )
+    if ( legacy_hpet_event.flags & HPET_EVT_DISABLE )
         return;
 
     hpet_id = hpet_read32(HPET_ID);
@@ -603,7 +603,7 @@ void hpet_disable_legacy_broadcast(void)
 
     spin_lock_irq(&legacy_hpet_event.lock);
 
-    legacy_hpet_event.flags |= HPET_EVT_DISALBE;
+    legacy_hpet_event.flags |= HPET_EVT_DISABLE;
 
     /* disable HPET T0 */
     cfg = hpet_read32(HPET_T0_CFG);
@@ -625,6 +625,9 @@ void hpet_broadcast_enter(void)
     int cpu = smp_processor_id();
     struct hpet_event_channel *ch = per_cpu(cpu_bc_channel, cpu);
 
+    if ( this_cpu(timer_deadline) == 0 )
+        return;
+
     if ( !ch )
         ch = hpet_get_channel(cpu);
     BUG_ON( !ch );